﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows;
using System.Windows.Media.Imaging;
using Microsoft.Win32;
using ZXing;
using ZXing.Common;
using ZXing.QrCode;

namespace BarCodeAndQR {
  /// <summary>
  /// MainWindow.xaml 的交互逻辑
  /// </summary>
  public partial class MainWindow: Window {
    public MainWindow() {
      InitializeComponent();
    }

    private string commonPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\barcodeAndQRCode";
    private void GenerateBarCode_OnClick(object sender, RoutedEventArgs e) {
      // 生成 EAN-13 条码
      // 1. 设置条码规格
      EncodingOptions encodingOptions = new EncodingOptions();
      // 必须设置宽高
      encodingOptions.Height = 130;
      encodingOptions.Width = 240;

      // 2. 生成条码并保存

      // 生成图片, 内容必须是12个数字或者是13个Checksum（校验和）
      // 获取图片路径：桌面
      string path = commonPath + "\\ENA-13-" + CodeContent.Text;
      string ext = ".jpg";
      string p = GetFilePath(path, ext);

      var img = GenerateCode(encodingOptions, BarcodeFormat.EAN_13, CodeContent.Text);
      img.Save(p, ImageFormat.Jpeg);

      MessageBox.Show("保存成功");
    }

    private void ReadBarCode_OnClick(object sender, RoutedEventArgs e) {
      // 设置解码选项
      DecodingOptions decodingOptions = new DecodingOptions();
      // 可能的条码格式
      decodingOptions.PossibleFormats = new List<BarcodeFormat> {
        BarcodeFormat.EAN_13
      };

      // 读取
      BarcodeReader reader = new BarcodeReader();
      reader.Options = decodingOptions;
      Result result = reader.Decode(new Bitmap(ImgPath.Text));
      ShowResult(result, "读取条码失败");
    }
    /// <summary>
    /// 显示结果信息
    /// </summary>
    /// <param name="result">读取结果</param>
    /// <param name="errorMsg">错误信息</param>
    /// <param name="successMsg">成功信息</param>
    private void ShowResult(Result result, string errorMsg = "读取失败", string successMsg = "读取到的内容为：") {
      if(result == null) {
        CodeContent.Text = errorMsg;
        MessageBox.Show(errorMsg);
        return;
      }
      CodeContent.Text = result.Text;
      MessageBox.Show($"{successMsg}{result.Text}");
    }

    private void OpenImg_OnClick(object sender, RoutedEventArgs e) {
      OpenFileDialog ofd = new OpenFileDialog();
      ofd.InitialDirectory = commonPath;
      ofd.Title = "选择条码图片";
      ofd.Filter = "图片|*.jpg;*.png|所有文件|*.*";
      ofd.Multiselect = false;
      ofd.ShowDialog();


      ImgPath.Text = ofd.FileName;
      if(string.IsNullOrEmpty(ImgPath.Text)) return;

      CodeImg.Source = new BitmapImage(new Uri(ImgPath.Text));
    }

    private void GenerateQR_OnClick(object sender, RoutedEventArgs e) {
      // 二维码：在水平和垂直方向的二维空间存储信息的条形码。
      // 常用码制：PDF417、QR Code、Code 49、Code 16K、Code One等。
      // 生成QR二维码
      // 设置
      QrCodeEncodingOptions options = new QrCodeEncodingOptions();
      // 设置编码格式，否则对于非ASCII码编码的文字会出现乱码
      options.CharacterSet = "UTF-8";
      options.Height = 200;
      options.Width = 200;
      options.Margin = 1;


      // 生成
      string path = commonPath + "\\QR_Code";
      string ext = ".jpg";
      string p = GetFilePath(path, ext);

      var img = GenerateCode(options, BarcodeFormat.QR_CODE, CodeContent.Text);
      img.Save(p, ImageFormat.Jpeg);
      MessageBox.Show("保存成功");
    }

    /// <summary>
    /// 生成条码
    /// </summary>
    /// <param name="options">条码选项</param>
    /// <param name="format">条码格式</param>
    /// <param name="codeContent">条码内容</param>
    private Bitmap GenerateCode(EncodingOptions options, BarcodeFormat format, string codeContent) {
      BarcodeWriter writer = new BarcodeWriter {
        Format = format,
        Options = options
      };
      Bitmap img = writer.Write(codeContent);

      return img;
    }

    /// <summary>
    /// 获取文件路径
    /// </summary>
    /// <param name="path">不带扩展名的文件路径</param>
    /// <param name="ext">扩展名</param>
    /// <returns></returns>
    private static string GetFilePath(string path, string ext) {
      string p = $"{path}{ext}";
      var i = 0;
      while(true) {
        if(!File.Exists(p)) {
          break;
        }
        p = $"{path}_{i}{ext}";
        i++;
      }
      return p;
    }

    private void ReadQRCode_OnClick(object sender, RoutedEventArgs e) {
      DecodingOptions options = new DecodingOptions();
      options.PossibleFormats = new List<BarcodeFormat> {
        BarcodeFormat.QR_CODE
      };

      BarcodeReader reader = new BarcodeReader();
      reader.Options = options;
      Result result = reader.Decode(new Bitmap(ImgPath.Text));
      ShowResult(result, "读取二维码失败", "读取到的二维码内容为：");
    }

    private void GenerateQRWithLogo_OnClick(object sender, RoutedEventArgs e) {
      // 生成带Logo的二维码

      QrCodeEncodingOptions options = new QrCodeEncodingOptions {
        CharacterSet = "UTF-8",
        Height = 200,
        Width = 200,
        Margin = 1
      };

      Bitmap img = GenerateCode(options, BarcodeFormat.QR_CODE, CodeContent.Text);

      // 在二维码上绘制Logo
      Bitmap logoImg = new Bitmap(ImgPath.Text);
      Graphics graphics = Graphics.FromImage(img);
      // 设置logo的大小和绘制的位置
      Rectangle logoRec = new Rectangle {
        Width = img.Width / 6,
        Height = img.Height / 6
      };
      // 中心点
      logoRec.X = img.Width / 2 - logoRec.Width / 2;
      logoRec.Y = img.Height / 2 - logoRec.Height / 2;
      // 绘图
      graphics.DrawImage(logoImg, logoRec);

      // 保存绘制完成的图片
      string filePath = commonPath + "\\QR_Code-Logo";
      string ext = ".jpg";
      string p = GetFilePath(filePath, ext);

      img.Save(p, ImageFormat.Jpeg);

      MessageBox.Show("生成成功");
    }
  }
}
